package IC.SymbolTable;

import java.util.LinkedHashMap;
import java.util.Map;

import IC.AST.ICClass;
import IC.SymbolTable.SemanticError;

public class GlobalSymbolTable extends SymbolTable
{

	private String icFileName;
	private Map<String,ClassSymbol> classEntries;

	public GlobalSymbolTable(String icFileName) 
	{
		super("global", null);
		this.classEntries = new LinkedHashMap<String, ClassSymbol>();
		this.icFileName = icFileName;
		this.stt = symbolTableType.GLOBAL;

	}


	public boolean isDeclaredAlreadyInCurrScopeGlobal(String symId)
	{
		if(classEntries.containsKey(symId))
		{
			return true;
		}

		return false;
	}

	public void addClass(ICClass c) throws SemanticError
	{
		String className = c.getName();
		if (!isDeclaredAlreadyInCurrScopeGlobal(className))
		{
			this.classEntries.put(className, new ClassSymbol(c));
		}

		else
		{
			throw new SemanticError("ClassSymbol "  + className + " was already declared");
		}


	}

	public ClassSymbol lookupClassSymbolInCurrScope (String id)
	{
		if (classEntries == null)
		{
			return null;			
		}

		return  classEntries.get(id);
	}


	// lookup for ClassSymbolTable - first in children, then in their children
	public ClassSymbolTable lookupClassSymbolTableRec(String name){

		ClassSymbolTable csm = null;


		for (SymbolTable st : childrenSymbolTables)
		{
			if (st.getId().equals( name))

			{
				return  (ClassSymbolTable)st; 
			}
		}
	
		for (SymbolTable symt : childrenSymbolTables)
		{
			csm = ((ClassSymbolTable)symt).lookupClassSymbolTableRec(name);     
			if (csm != null)
			{
				break;
			}
		}
		return csm;
	}




	public String toString(){
		String str = "Global Symbol Table: "+icFileName;

		// print list of symbols (classes)
		for(ClassSymbol s: classEntries.values()){
			str += "\n\tClass: "+s.getId();
		}

		// print list of children tables
		if(!childrenSymbolTables.isEmpty()){
			str += "\nChildren tables: ";
			for(SymbolTable st: childrenSymbolTables)
				str += st.getId()+", ";
			str = str.substring(0, str.length()-2);
		}
		str += "\n\n";

		// recursively print class symbol tables
		for(SymbolTable symt: childrenSymbolTables){
			str += symt.toString();
		}

		return str;
	}



}